package com.xzzz.expand.es.core.utils;

import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.xzzz.expand.es.core.annotation.EsId;
import com.xzzz.expand.es.core.annotation.EsIndex;
import com.xzzz.expand.es.core.common.EsConstants;
import com.xzzz.expand.es.core.common.EsException;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;

@Slf4j
public class EsUtil {


    /**
     * 对字段进行关键字封装
     * @param field 字段名称
     * @return 字段名称.keyword
     */
    public static String Keyword(String field) {
        if (StrUtil.isBlank(field)) {
            throw new EsException("字段不得为空");
        }

        return field + EsConstants.KEYWORD;
    }

    public static String getIdByAnnotation(Object source) {
        return getIdByAnnotation(source, false);
    }

    /**
     * 从对象中获取被 {@link EsId} 注解的文档ID值
     *
     * @param source 对象
     * @param strictId 如果为 true, 则对象中必须包含被 {@link EsId} 注解的字段, 若没有将抛出错误
     * @return 文档ID
     */
    public static String getIdByAnnotation(Object source, boolean strictId) {
        if (source == null) {
            throw new EsException("参数不得为空");
        }

        Field[] fields = source.getClass().getDeclaredFields();

        if (fields.length == 0) {
            if (strictId) {
                throw new IllegalArgumentException("对象中没有被 [@EsId] 注解标识的字段, 请检查对象. 如果需要自动生成ID, 请使用 getIdByAnnotation(Object source)");
            }
            return null;
        }

        Field idField = null;
        for (Field field : fields) {
            if (AnnotationUtil.hasAnnotation(field, EsId.class)) {
                if (idField != null) {
                    throw new IllegalArgumentException("发现多个字段属性包含 [@EsId] 注解");
                } else {
                    idField = field;
                }
            }
        }

        if (idField == null) {
            if (strictId) {
                throw new IllegalArgumentException("需要使用 [@EsId] 注解标识文档ID");
            }
            return null;
        }

        Object id = ReflectUtil.getFieldValue(source, idField.getName());
        if (id == null) {
            if (strictId) {
                throw new IllegalArgumentException("需要使用 [@EsId] 注解标识文档ID");
            }
            return null;
        }
        return String.valueOf(id);
    }

    /**
     * 从对象中获取被 {@link EsIndex} 注解的索引名称
     *
     * @param source 对象
     * @return 索引名称
     */
    public static String getIndexByAnnotation(Object source) {
        if (source == null) {
            throw new EsException("参数不得为空");
        }

        EsIndex esIndex = AnnotationUtil.getAnnotation(source.getClass(), EsIndex.class);
        if (esIndex == null) {
            throw new IllegalArgumentException("需要使用 [@EsIndex] 注解标识文档所在索引");
        }

        String indexName = esIndex.name();
        if (StrUtil.isBlank(indexName)) {
            throw new EsException("未能从 [@EsIndex] 注解中获取到索引名称 [name]");
        }

        return indexName;
    }
}










































